package com.ushio.gougouwangguo.controller;

import com.alibaba.excel.EasyExcel;
import com.ushio.commonmodule.pojo.result.Result;
import com.ushio.gougouwangguo.entity.mysql.Person;
import com.ushio.gougouwangguo.entity.vo.WeaponTreeNodeVo;
import com.ushio.gougouwangguo.entity.vo.WeaponWarehouseVo;
import com.ushio.gougouwangguo.service.CampService;
import com.ushio.gougouwangguo.utils.multithreading.MillionLevelExport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RestController
@RequestMapping("/camp")
@Tag(name = "CampController", description = "武器仓库")
public class CampController {

    @Autowired
    CampService campService;
    private final ExecutorService executorService = Executors.newFixedThreadPool(5);

    @GetMapping("/weapon-warehousel-select")
    @Operation(summary="获取所有武器",description = "获取所有武器")
    private Result<List<WeaponTreeNodeVo>> weaponWarehouselSelect(){

        try{

            List<WeaponTreeNodeVo> list = campService.weaponWarehouselSelect();
            return Result.success(list);

        }catch (Exception e){
                e.printStackTrace();
            return Result.fail(e.getMessage());
        }

    };

    @GetMapping("/weapon-select")
    @Operation(summary="根据持有人获取武器",description = "根据持有人获取武器")
    private Result<List<WeaponWarehouseVo>> weaponelSelect(){

        try{

            List<WeaponWarehouseVo> list = campService.weaponelSelect();
            return Result.success(list);

        }catch (Exception e){
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }

    };

    @GetMapping("/protective-gear-select")
    @Operation(summary="根据持有人获取防具",description = "根据持有人获取防具")
    private Result<List<WeaponWarehouseVo>> getProtectiveGearSelect(){

        try{

            List<WeaponWarehouseVo> list = campService.getProtectiveGearSelect();
            return Result.success(list);

        }catch (Exception e){
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }

    };

    @GetMapping("/shoes-select")
    @Operation(summary="根据持有人获取鞋子",description = "根据持有人获取鞋子")
    private Result<List<WeaponWarehouseVo>> getShoesGearSelect(){

        try{

            List<WeaponWarehouseVo> list = campService.getShoesGearSelect();
            return Result.success(list);

        }catch (Exception e){
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }

    };

    @GetMapping("/exportOfMillionsOfData")
    @Operation(summary="百万数据导出",description = "百万数据导出")
    private void exportOfMillionsOfData() throws InterruptedException {

        String fileName = "million_persons.xlsx";
        int total = 1_000_000;   // 总数据量 100 万
        List<Person> batch = new ArrayList<>();

        // 使用 EasyExcel 分批写入
        for (int start = 0; start < total; start ++) {

            batch.add(new Person(
                    start,
                    "Name_" + start,
                    (int) (Math.random() * 100),
                    (start % 2 == 0 ? "男" : "女")
            ));

        }

        List<List<Person>> partition = partition(batch, 100000);

        for (List<Person> personList :partition) {
            MillionLevelExport millionLevelExport = new MillionLevelExport(personList);
            Thread thread = new Thread(millionLevelExport);
            thread.start();
            thread.join();
        }


        System.out.println("百万数据已生成到本地 Excel：" + fileName);

    };

    private <T> List<List<T>> partition(List<T> list, int size) {
        List<List<T>> parts = new ArrayList<>();
        for (int i = 0; i < list.size(); i += size) {
            parts.add(list.subList(i, Math.min(i + size, list.size())));
        }
        return parts;
    }
}
